#encoding: utf-8
#encoding: utf-8
from flask import current_app
from .. import db, bcrypt, login_manager
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask_login import UserMixin
from datetime import datetime

class User(db.Model, UserMixin):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), nullable=True, unique=True)
    email = db.Column(db.String(40), nullable=True, unique=True, index=True)
    password = db.Column(db.String(60), nullable=True)
    role_id = db.Column(db.Integer, db.ForeignKey("roles.id"))
    is_confirmed = db.Column(db.Boolean, default=False)
    is_valid = db.Column(db.Boolean, default=True)
    last_logined_time = db.Column(db.DateTime)
    status = db.Column(db.Boolean, default=True)
    created_time = db.Column(db.DateTime)

    articles = db.relationship("Article", backref="author", lazy="dynamic")

    def __init__(self, username, email, password):
        self.username = username
        self.email = email
        self.password = bcrypt.generate_password_hash(password).decode("utf-8")
        self.created_time = datetime.now()

    def __repr__(self):
        return "<User {0}>".format(self.username)
    # 添加
    def add(self):
        db.session.add(self)
        db.session.commit()

    # 生成密令
    def generate_confirmation_token(self, expiration = 60 * 60):
        s = Serializer(current_app.config["SECRET_KEY"], expiration)
        return s.dumps({"confirm_id": self.id})

    # 验证密令
    def confirm_token(self, token):
        s = Serializer(current_app.config["SECRET_KEY"])
        try:
            data = s.load(token)
        except:
            return False

        if data.get("confirm_id") != self.id:
            return False

        # 如果验证通过
        self.is_confirmed = True
        db.session.add(self)
        db.session.commit()

        return True

    # 重设最后登录时间
    def setLastLoginedTime(self):
        self.last_logined_time = datetime.now()
        db.session.add(self)
        db.session.commit()

    # 验证密令，获取用户信息
    @classmethod
    def getUserByConfirmToken(cls, token):
        s = Serializer(current_app.config["SECRET_KEY"])
        try:
            data = s.loads(token)
        except:
            return None
        # 获取用户id
        user_id = data.get("confirm_id")
        # 通过用户id获取用户信息
        user = cls.getUserById(user_id)
        # 判断user是否存在，且未被验证过的
        if user and not user.is_confirmed:
            user.is_confirmed = True
            db.session.add(user)
            db.session.commit()
        # 返回用户信息
        return user


    # 判断用户名是否存在
    @classmethod
    def is_username_existed(cls, username):
        user = cls.query.filter_by(is_valid=True, username=username).first()
        is_existed = bool(user)
        return is_existed

    # 判断邮箱是否存在
    @classmethod
    def is_email_existed(cls, email):
        result = cls.query.filter_by(is_valid=True, email=email).first()
        if result:
            return True
        else:
            return False

    # 判断密码是否正确
    def verify_password(self, password):
        return bcrypt.check_password_hash(self.password, password)

    # 通过邮箱地址获取用户
    @classmethod
    def getUserByEmail(cls, email):
        result = User.query.filter_by(is_valid=True, email=email).first()
        return result

    # 通过id获取用户
    @classmethod
    def getUserById(cls, id):
        user = cls.query.filter_by(is_valid=True, id=id).first()
        return user

    # 获取用户列表
    @classmethod
    def getList(cls):
        rows = cls.query.filter_by(is_valid=True).all()
        users = []
        for row in rows:
            article_count = row.articles.count()
            user = {
                "id": row.id,
                "username": row.username,
                "email": row.email,
                "article_count": article_count,
                "status": row.status,
                "last_logined_time": datetime.timestamp(row.last_logined_time) if row.last_logined_time else "",
                "created_time": datetime.timestamp(row.created_time)
            }
            users.append(user)
        print("-----users-----")
        print(users)
        return {"list": users}

    # 停止用户、启用用户
    @classmethod
    def upgradeStatusById(cls, id):
        user = cls.query.filter_by(is_valid=True, id=id).first()
        if user:
            user.status = not user.status
            db.session.add(user)
            db.session.commit()


    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))
